package cn.bellychang.wangzheng.lru;

import java.util.LinkedList;

/**
 * @author ChangLiang
 * @date 2020/10/30
 */
public class LinkedLruCache<T> implements LruCache<T> {

    private LinkedList<T> linkedList;

    private int capacity = 4;

    public LinkedLruCache() {
        linkedList = new LinkedList<>();
    }

    public LinkedLruCache(int capacity) {
        linkedList = new LinkedList<>();
        this.capacity = capacity;
    }

    private boolean isFull() {
        return linkedList.size() >= this.capacity;
    }

    private int getIndex(T t) {
        for (int i = 0; i < linkedList.size(); i++) {
            if (linkedList.get(i).equals(t)) {
                return i;
            }
        }
        return -1;
    }

    @Override
    public void putIntoCache(T t) {
        if (!isFull()) {
            int index = getIndex(t);
            if (index != -1) {
                // 如果存在 那么就将其移除 并放到最前面
                linkedList.remove(index);
            }
            this.linkedList.addFirst(t);
        } else {
            // 需要判断是否存在 不存在 那么就移除最后一个
            // 如果存在 那么就将其移除 并放到最前面
            int index = getIndex(t);
            if (index == -1) {
                linkedList.removeLast();
            } else {
                linkedList.remove(index);
            }
            linkedList.addFirst(t);
        }
    }

    /**
     * 这样写思路是对的 实际上getFromCache并没有任何意义
     * 其传入的参数应该是ID  输出的是对象
     * 每一个get就相当于是一次使用 也是要调整链表顺序的
     * @param t
     * @return
     */
    @Override
    public T getFromCache(T t) {
        int index = getIndex(t);
        if (index == -1) {
            return null;
        }
        return linkedList.get(index);
    }

    @Override
    public String toString() {
        return "LinkedLruCache{" +
                "linkedList=" + printLinkedList() +
                ", capacity=" + capacity +
                '}';
    }

    public String printLinkedList() {
        StringBuilder builder = new StringBuilder();
        linkedList.forEach(v -> builder.append(v.toString()).append("->"));
        String s = builder.toString();
        return s.endsWith("->") ? s.substring(0, s.length() - 2) : s;
    }
}
